/**
 * 
 */
package de.uni_leipzig.informatik.asv.util;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import cern.jet.random.tdouble.DoubleUniform;
import cern.jet.random.tdouble.engine.MersenneTwister64;
/**
 * @author Christoph Teichmann
 * created May 29, 2014 9:22:16 PM
 * @version 0.1
 */
public class MixingIterator<E> implements Iterator<E>
{
	/**
	 * 
	 */
	private final ArrayList<E> data;
	/**
	 * 
	 */
	int p = 0;
	/**
	 * 
	 */
	private final int[] positions;
	/**
	 * 
	 */
	private final DoubleUniform du = new DoubleUniform(new MersenneTwister64(new Date()));
	/**
	 * 
	 * @param data
	 */
	public MixingIterator(ArrayList<E> data)
	{
		this.positions = new int[data.size()];
		int l = positions.length-1;
		for(int i=0;i<positions.length;++i)
		{this.positions[i] = i;}
		for(int i=0;i<positions.length;++i)
		{
			int val = positions[i];
			int ex = du.nextIntFromTo(i, l);
			positions[i] = positions[ex];
			positions[ex] = val;
		}
		this.data = data;
	}
	/* (non-Javadoc)
	 * @see java.util.Iterator#hasNext()
	 */
	@Override
	public boolean hasNext()
	{return p < this.positions.length;}
	/* (non-Javadoc)
	 * @see java.util.Iterator#next()
	 */
	@Override
	public E next()
	{
		int  q = this.positions[p++];
		if(q < this.data.size())
		{return data.get(q);}
		else
		{return data.get(du.nextIntFromTo(0, data.size()-1));}
	}
	/* (non-Javadoc)
	 * @see java.util.Iterator#remove()
	 */
	@Override
	public void remove()
	{}
}